
package com.hxrk.cecardvr;

import android.annotation.SuppressLint;
import android.app.Service;
import android.content.Intent;
import android.graphics.Bitmap;
import android.media.AudioFormat;
import android.media.AudioRecord;
import android.media.MediaCodec;
import android.media.MediaCodecInfo;
import android.media.MediaFormat;
import android.media.MediaRecorder;
import android.os.Build;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.util.Log;
import android.widget.Toast;

import com.hxrk.easyface.EasyFace;
import com.hxrk.jni.Mp4v2Native;
import com.mediatek.carcorder.CameraDevice;

import org.opencv.core.Mat;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.ByteBuffer;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import static com.hxrk.cecardvr.CamParameter.mMainCameraDevice;
import static java.lang.Thread.sleep;


public class CamService extends Service {
    private static final String TAG = "CamService";

    //录像参数，index 0：前录  1：后录  2：前后合成
    public static int CamNumber = 5;
    public static int camMIPI_ID = 4;      //MIPI Camera 所在数组ID
    public static CamParameter[] camParameters = new CamParameter[CamNumber];

    public static boolean isACC = true;
    public static boolean isRTSP = false;

    // 是否正在进行报警操作
    public static boolean isAlarm = false;
    public static long lRTSPTime = 0;           //rtp开始控制时时间
    public static int nMipiBackStatus = 0;      //MIPI编码数据是否返回状态
    public static long lRTP_YS = 20 * 60 * 1000;  //默认rtp开始控制后mipi返回数据15分钟
    public static int PTType = 1;   //文件支持平台类型 0：交科院808  1：深圳交委(默认)   2:公路院905过检  3:佛山905  接收DidiMain控制


    public static int flag_v = 0;               //标记   0：不标记   1：标记
    public static int lock_v = 0;               //锁存   0：不锁存   1：锁存
    public static int width1_v = 640;          //通道1录像宽
    public static int height1_v = 480;          //通道1录像高
    public static int width2_v = 640;          //通道2录像宽 MIPI
    public static int height2_v = 480;          //通道2录像高 MIPI
    public static int vediosave1_v = 1;         //通道1存储     0：不存储   1：存储
    public static int vediosave2_v = 1;         //通道2存储     0：不存储   1：存储

    // 人脸识别号
    public static String IDNumber = "144312";
    public static int FaceStatus = 0;

    // USB录制是否传入时间水印
    public static boolean IsWatermarkexDate = false;

    // 是否异常重启过
    public static boolean isRebootERR = false;

    // 保存最近N个视频文件,用于报警时拷贝
    private int saveFileNumber = 4;
    public static List<String> saveFilsMIPI = new ArrayList<>();
    public static List<String> saveFilsUSB = new ArrayList<>();

    public void onCreate() {
        super.onCreate();
        Log.i(TAG, "onCreate called.");

        for (int i = 0; i < CamNumber; i++) {
            camParameters[i] = new CamParameter(i);
            if(i == 0){
                CamService.camParameters[i].IMG_TYPE = CamParameter.FMT_TYPE_H264;
                CamService.camParameters[i].DEV_TYPE = CamParameter.DEV_TYPE_USB;
            }
            if (i == camMIPI_ID) {
                CamService.camParameters[camMIPI_ID].initBmp(width2_v, height2_v, CamParameter.FMT_TYPE_H264, 90000, 25, 16000, 1024, CamParameter.DEV_TYPE_MIPI);
            }

            if(i == 0 || i == camMIPI_ID){
                //保存视频线程
                SaveMp4v2VideoLoop savemp4v2VideoLoop = new SaveMp4v2VideoLoop(camParameters[i]);
                savemp4v2VideoLoop.start();
            }
        }

        AudioLoop audioLoop = new AudioLoop();
        audioLoop.start();

        OpenVideoLoop openVideoLoop = new OpenVideoLoop();
        openVideoLoop.start();

        CopyfiletoSDLoop copyfiletoSDLoop = new CopyfiletoSDLoop();
        copyfiletoSDLoop.start();

        TCPListen tcplisten = new TCPListen();
//        tcplisten.start();
    }

    class TCPListen extends Thread {

        TCPListen() {}

        public void run() {
            init();
        }

        public static final int PORT = 12345;//监听的端口号

        public void init() {
            try {
                ServerSocket serverSocket = new ServerSocket(PORT);
                while (true) {
                    // 一旦有堵塞, 则表示服务器与客户端获得了连接
                    Socket client = serverSocket.accept();
                    // 处理这次连接
                    new HandlerThread(client);
                }
            } catch (Exception e) {
                LogUtils.e(TAG, "服务器异常: " + e.getMessage());
            }
        }

        private class HandlerThread implements Runnable {
            private Socket socket;
            public HandlerThread(Socket client) {
                socket = client;
                new Thread(this).start();
            }

            public void run() {
                try {
                    InputStream input = socket.getInputStream();
                    OutputStream out = socket.getOutputStream();
                    byte[] rdata = new byte[1];
                    byte[] wdata;
                    byte[] wdata1;

                    boolean bFlag = false;
                    while (true) {
//                        LogUtils.d("dddddddddddddddddddddddddd");
                        int len = input.read(rdata);
                        CamParameter campr = null;
                        for (int i = 0; i < CamService.camParameters.length; i++) {
                            if (CamService.camParameters[i].IMG_TYPE == CamParameter.FMT_TYPE_H264 && CamService.camParameters[i].DEV_TYPE == CamParameter.DEV_TYPE_USB) {
                                campr = CamService.camParameters[i];
                                break;
                            }
                        }

                        if (rdata[0] == 0) {
                            synchronized (campr.facesyn) {
                                org.opencv.android.Utils.matToBitmap(campr.mCameraFrame[1].rgba(), campr.bmpFace);
                                wdata = ImageUtil.bitmapToNv21(campr.bmpFace, 1280, 720);
                            }
                            out.write(wdata);
                        }  else if (rdata[0] == 1){
                            wdata1 = getBitmapPk(campr.bmpFace);
                            out.write(wdata1);
                        }
                    }
                } catch (Exception e) {
                    LogUtils.e(TAG,"服务器 run 异常: " + e.getMessage());
                } finally {
                    if (socket != null) {
                        try {
                            socket.close();
                        } catch (Exception e) {
                            socket = null;
                            LogUtils.e(TAG,"服务端 finally 异常:" + e.getMessage());
                        }
                    }
                }
            }

            private byte[] getBitmapPk(Bitmap bitmap){
                ByteArrayOutputStream baos = new ByteArrayOutputStream();
                bitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos);
                byte[] datas = baos.toByteArray();
                int len = datas.length + 4;
                LogUtils.d("服务器 bitmapLen  = " + len);
                byte[] dataPk = new byte[datas.length + 4];
                dataPk[0] = (byte)((len >> 24) & 0xFF);
                dataPk[1] = (byte)((len >> 16) & 0xFF);
                dataPk[2] = (byte)((len >> 8) & 0xFF);
                dataPk[3] = (byte)(len & 0xFF);

                System.arraycopy(datas, 0, dataPk, 4, len - 4);

                return dataPk;
            };
        }
    }

    @Override
    public void onDestroy() {
        LogUtils.d("CamService  onDestroy");
        //关闭socket

        try {
            sleep(1200);
        } catch (Exception e) {
            e.printStackTrace();
        }

        super.onDestroy();
        Log.i(TAG, "onDestroy called.");
    }

    class OpenVideoLoop extends Thread {

        // 0:不存在 1:存在
        private int sdStatus = -1;

        OpenVideoLoop() {
        }

        public void run() {
            while (true) {
                try {
//                    LogUtils.d("OpenVideoLoop videoStatus = " + Boolean.toString(videoStatus) + "   isreboot = " + Boolean.toString(isreboot));

                    // 如果SD卡存在则需要判断SD卡拔出，防止SD卡插拔导致程序异常

                    if (isACC || isRTSP){
                        String pathSD = Utils.getPath2();
                        if (sdStatus == -1){
                            if (!pathSD.isEmpty()) {
                                sdStatus = 1;
                                LogUtils.d("SD卡默认存在");
                            }else {
                                sdStatus = 0;
                                LogUtils.d("SD卡默认不存在");
                            }
                            continue;
                        }

                        if (sdStatus == 0){
                            if (!pathSD.isEmpty()) {
                                sdStatus = 1;
                                LogUtils.d("SD卡插入 重新开始录像");
                                closeVideo();
                                continue;
                            }
                        }

                        if (sdStatus == 1){
                            if (pathSD.isEmpty()) {
                                sdStatus = 0;
                                LogUtils.d("SD卡拔出  录像程序重启");
                                android.os.Process.killProcess(android.os.Process.myPid());
                                continue;
                            }
                        }

                        Mp4v2Native.getInstance().videoopen(width1_v, height1_v);
                        sleep(3000);
                        continue;
                    }

                    if (isAlarm){
                        Mp4v2Native.getInstance().videoopen(width1_v, height1_v);
                        sleep(100);
                        continue;
                    }
                    sleep(3000);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }

    public static void closeVideo(){
        //LogUtils.d("===================jnimp4v2_close usb Video========================");
        for (int i = 0; i < CamNumber; i++) {
            camParameters[i].savetik = 0;
            camParameters[i].deviceState = false;
            if (camParameters[i].DEV_TYPE == CamParameter.DEV_TYPE_USB && (camParameters[i].IMG_TYPE == CamParameter.FMT_TYPE_H264)){
                Mp4v2Native.getInstance().videoclose(i);
            }
        }
    }


    @SuppressLint("NewApi")
    class SaveMp4v2VideoLoop extends Thread {
        private CamParameter mCamParameter = null;

        private int MediaID = 0;

        SaveMp4v2VideoLoop(CamParameter par) {
            mCamParameter = par;
        }

        public void run() {
            //启动读文件
            ReadVideoLoop readVideoLoop = new ReadVideoLoop(mCamParameter);
            readVideoLoop.start();

            //启动水印写
            WatermarkLoop watermarkLoop = new WatermarkLoop(mCamParameter);
            watermarkLoop.start();

            while (true) {
                try {
                    //判断MIPI是否返回编码数据
                    if (isRTSP) {
                        if (!isACC){
                            // 打开USB电源
                            Utils.writeUSBPowerFile(1);
                        }
                        if (System.currentTimeMillis() - lRTSPTime < lRTP_YS) {
                            if (mCamParameter.DEV_TYPE == CamParameter.DEV_TYPE_MIPI && nMipiBackStatus != 3 && mCamParameter.savefile) {
                                mCamParameter.setMIPIBack(3);
                                nMipiBackStatus = 3;
                                Log.e("jnimp4v2", "开启MIPI编码返回!!!!");
                            }
                        } else {
                            if (mCamParameter.DEV_TYPE == CamParameter.DEV_TYPE_MIPI && nMipiBackStatus != 0 && mCamParameter.savefile) {
                                mCamParameter.setMIPIBack(0);
                                nMipiBackStatus = 0;
                                Log.e("jnimp4v2", " 关闭MIPI编码返回!!!!");
                            }
                            isRTSP = false;

                            if (!isACC){
                                closeVideo();
                                // 关闭USB电源
                                Utils.writeUSBPowerFile(0);
                            }
                        }
                    }

                    //时间段停止
                    if ((System.currentTimeMillis() - mCamParameter.saveStart >= mCamParameter.savetik)) {
                        if (mCamParameter.savefile && mCamParameter.DEV_TYPE == CamParameter.DEV_TYPE_USB) {
                            // 停止录像
                            LogUtils.d("closeMp4File camera id:" + mCamParameter.CamID+" mp4file time:"+(System.currentTimeMillis() - mCamParameter.saveStart));
                            mCamParameter.closeMp4File();

                            int LSH = mCamParameter.CMDBundle.getInt("LSH", -1);
                            mCamParameter.CMDBundle.putInt("MediaID", this.MediaID);
                            mCamParameter.CMDBundle.putInt("MediaType", 2);
                            mCamParameter.CMDBundle.putInt("MediaCode", 4);
                            mCamParameter.CMDBundle.putInt("EventCode", 1);
                            mCamParameter.CMDBundle.putLong("StartTime", mCamParameter.saveStart);
                            int Channclid = 0;
                            for (int i = 0; i <= mCamParameter.CamID; i++) {
                                if (CamService.camParameters[i].IMG_TYPE == CamParameter.FMT_TYPE_H264) {
                                    Channclid++;
                                }
                            }
                            mCamParameter.CMDBundle.putInt("ChannclID", Channclid);
                            mCamParameter.CMDBundle.putInt("PTType", PTType);
                            mCamParameter.CMDBundle.putInt("Cause", 0);
                            mCamParameter.CMDBundle.putString("FilePath", mCamParameter.savefilename);
                            File file = new File(mCamParameter.savefilename);
                            if (file.exists()) {
                                mCamParameter.CMDBundle.putInt("FileLength", (int) file.length());
                            }
                            if (LSH != -1) {
                                ArrayList<Integer> mMedias = new ArrayList<Integer>();
                                mMedias.add(this.MediaID);
                                mCamParameter.CMDBundle.putIntegerArrayList("mMedias", mMedias);
                                mCamParameter.CMDBundle.putInt("EventCode", 0);
                                mCamParameter.CMDBundle.putInt("Cause", 3);
                                mCamParameter.CMDBundle.putInt("Result", 0);
                                LogUtils.d("时间段停止 LSH = " + LSH);
                                MyApplication.mDvrManager.mDvrCallBack.doVedio(mCamParameter.CMDBundle);
                                mCamParameter.CMDBundle.putInt("LSH", -1);
                            }
                            // 保存多媒体信息在数据库
                            if (MyApplication.mDvrManager.mDvrCallBack != null) {
                                MyApplication.mDvrManager.mDvrCallBack.AddMediaEx(mCamParameter.CMDBundle);
                            }
                        }
                    }

                    //只保存264格式
                    if ((isACC || isRTSP || isAlarm)
                            && !mCamParameter.savefile
                            && mCamParameter.IMG_TYPE == CamParameter.FMT_TYPE_H264
                            && (mCamParameter.CamID < camMIPI_ID ? (vediosave1_v == 1) : (vediosave2_v == 1))
                            && mCamParameter.deviceState) {
                        this.MediaID = MyApplication.GetMediaID();
                        String lock_flag = CamService.lock_v == 1 ? "_lock" : "";
                        lock_flag += CamService.flag_v == 1 ? "_flag" : "";
                        lock_flag += MyApplication.getAlarm() ? "_alarm" : "";
                        mCamParameter.savefilename = Utils.getCreatFileName(mCamParameter.DEV_TYPE, true, lock_flag, this.MediaID, 0, 0);

                        if (!mCamParameter.savefilename.isEmpty()) {
                            mCamParameter.CMDBundle.putString("StartSJ", new SimpleDateFormat("yyMMddHHmmss").format(System.currentTimeMillis()));   //开始时间
                            LogUtils.d("usb createMp4File name :"+mCamParameter.savefilename);
                            mCamParameter.createMp4File(mCamParameter.savefilename);
                            if (mCamParameter.DEV_TYPE != CamParameter.DEV_TYPE_MIPI) {
                                // USB
                                synchronized (saveFilsUSB) {
                                    if (saveFilsUSB.size() == saveFileNumber) {
                                        saveFilsUSB.remove(0);
                                    }
                                    saveFilsUSB.add(mCamParameter.savefilename);
                                }
                            } else {
                                // MIPI
                                synchronized (saveFilsMIPI) {
                                    if (saveFilsMIPI.size() == saveFileNumber) {
                                        saveFilsMIPI.remove(0);
                                    }
                                    saveFilsMIPI.add(mCamParameter.savefilename);
                                }
                            }
                        }
                    }
                    sleep(1000);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }

    class ReadVideoLoop extends Thread {
        private CamParameter mCamParameter = null;

        ReadVideoLoop(CamParameter par) {
            mCamParameter = par;
        }

        public void run() {

            while (true) {
                try {
                    if (mCamParameter.DEV_TYPE == CamParameter.DEV_TYPE_USB
                            && ((mCamParameter.IMG_TYPE == CamParameter.FMT_TYPE_H264 && mCamParameter.savefile) || isRTSP)) {
                        mCamParameter.videoread();
                    }
                    else {
                        sleep(500);
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }

    @SuppressLint("NewApi")
    class AudioLoop extends Thread {
        public void run() {
            int bufferReadResult = 0;
            byte[] audiooutput = null;

            try {
                // 音频硬编码
                MediaCodec mediaAudioCodec = MediaCodec.createEncoderByType("audio/mp4a-latm");
                MediaFormat mediaAudioFormat = MediaFormat
                        .createAudioFormat("audio/mp4a-latm", 16000, 1);
                mediaAudioFormat.setInteger(MediaFormat.KEY_AAC_PROFILE,
                        MediaCodecInfo.CodecProfileLevel.AACObjectLC);
                mediaAudioFormat.setInteger(MediaFormat.KEY_CHANNEL_COUNT, 1);
                mediaAudioFormat.setInteger(MediaFormat.KEY_BIT_RATE, 96000);
                mediaAudioCodec.configure(mediaAudioFormat, null, null,
                        MediaCodec.CONFIGURE_FLAG_ENCODE);
                mediaAudioCodec.start();

                // 录音
                int bufferSize = AudioRecord.getMinBufferSize(16000, AudioFormat.CHANNEL_IN_MONO,
                        AudioFormat.ENCODING_PCM_16BIT);
                AudioRecord audioRecord = new AudioRecord(MediaRecorder.AudioSource.MIC, 16000,
                        AudioFormat.CHANNEL_IN_MONO,
                        AudioFormat.ENCODING_PCM_16BIT, bufferSize * 2);
                audioRecord.startRecording();

                byte[] bBuf = new byte[bufferSize];
                audiooutput = new byte[bufferSize * 2];

                while (true) {
                    try {
                        if (isACC || isRTSP || isAlarm) {
                            bufferReadResult = audioRecord.read(bBuf, 0, bufferSize);
                            if (bufferReadResult > 0) {
                                //AAC硬编码，并保存
                                EncodeAAC(mediaAudioCodec, bBuf, audiooutput);
                            }
                        } else {
                            sleep(1000);
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    @SuppressLint("NewApi")
    public int EncodeAAC(MediaCodec mediaAudioCodec, byte[] input, byte[] output) {
        int pos = 0;
        try {
            ByteBuffer[] inputBuffers = mediaAudioCodec.getInputBuffers();
            ByteBuffer[] outputBuffers = mediaAudioCodec.getOutputBuffers();
            int inputBufferIndex = mediaAudioCodec.dequeueInputBuffer(-1);
            if (inputBufferIndex >= 0) {
                ByteBuffer inputBuffer = inputBuffers[inputBufferIndex];
                inputBuffer.clear();
                inputBuffer.put(input);
                mediaAudioCodec.queueInputBuffer(inputBufferIndex, 0, input.length, 0, 0);
            }
            MediaCodec.BufferInfo bufferInfo = new MediaCodec.BufferInfo();
            int outputBufferIndex = mediaAudioCodec.dequeueOutputBuffer(bufferInfo, 0);

            do {
                if (outputBufferIndex >= 0) {
                    ByteBuffer outputBuffer = outputBuffers[outputBufferIndex];

                    byte[] outData = new byte[bufferInfo.size];
                    outputBuffer.get(outData);

                    // 保存音频到文件
                    for (int i = 0; i < CamService.CamNumber; i++) {
                        if (CamService.camParameters[i].IMG_TYPE == CamParameter.FMT_TYPE_H264) {
                            CamService.camParameters[i].updateAudioData2(outData, outData.length);
                        }
                    }

                    System.arraycopy(outData, 0, output, pos, outData.length);
                    pos += outData.length;

                    mediaAudioCodec.releaseOutputBuffer(outputBufferIndex, false);
                    outputBufferIndex = mediaAudioCodec.dequeueOutputBuffer(bufferInfo, 0);

                } else if (outputBufferIndex == MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED) {
                    outputBuffers = mediaAudioCodec.getOutputBuffers();
                } else if (outputBufferIndex == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) {
                    MediaFormat format = mediaAudioCodec.getOutputFormat();
                    format = null;
                }
            } while (outputBufferIndex >= 0);
        } catch (Exception t) {
            t.printStackTrace();
        }
        return pos;
    }

    Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case 0:
                    Toast.makeText(CamService.this, (String) msg.obj, Toast.LENGTH_LONG).show();
                    break;
                case 1:
                    Toast.makeText(CamService.this, (String) msg.obj, Toast.LENGTH_LONG).show();
                    break;
            }
        }
    };

    /**
     * 遍历拷贝文件， 内置SD卡拷贝到外置SD卡
     *
     * @param path
     * @return
     */
    public void CopyFiles(String rootpath, String path, String dispath) {
        try {
            File file = new File(path);
            if (file.exists()) {
                if (file.isFile()) {
                    String filename = file.getAbsolutePath();
                    //不复制正常保存文件
                    if (!Utils.checkfile(filename))
                        return;

                    // sd卡文件不存在即拷贝
                    File sdfile = new File(filename.replaceFirst(rootpath, dispath));
                    if (!sdfile.exists() || sdfile.length() != file.length() && Utils.deleteFileSize(dispath, 1)) {
                        Log.d(TAG, "拷贝文件1  " + filename + "  到  " + sdfile.getAbsolutePath());
                        Message message = new Message();
                        message.what = 0;
                        message.obj = "正在拷贝" + filename + "至SD卡中，请等待!!!";
//                        handler.sendMessage(message);
                        if (CopyFileUtil.copyFile(filename, sdfile.getAbsolutePath(), false)) {
                            // 删除已拷贝完成的文件
                            file.delete();
                            // 拷贝单个文件完成
                            Log.d(TAG, "拷贝文件完成");
                            Message message1 = new Message();
                            message1.what = 1;
                            message1.obj = filename + "----拷贝完成!";
//                            handler.sendMessage(message1);
                        }
                    }
                } else if (file.isDirectory()) {
                    File files[] = file.listFiles();
                    for (File f : files) {
                        CopyFiles(rootpath, f.getAbsolutePath(), dispath);
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @SuppressLint("NewApi")
    class CopyfiletoSDLoop extends Thread {
        public void run() {
            while (true) {
                try {
                    String sdpath = Utils.getPath2();
                    if (!sdpath.isEmpty()) {

                        String temppath = Utils.getPath1();
                        if (!temppath.isEmpty()) {
//                            synchronized (camParameters[2].audiosyn) {
                            CopyFiles(temppath, temppath, sdpath);
//                            }
                        }
                    }
                    sleep(5000);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }

    @SuppressLint("NewApi")
    class WatermarkLoop extends Thread {
        private CamParameter mCamParameter = null;

        WatermarkLoop(CamParameter par) {
            mCamParameter = par;
        }

        public void run() {
            SimpleDateFormat fmt = new SimpleDateFormat("yyyyMMdd-HH:mm:ss");



            while (true) {
                try {
                    String suffix = fmt.format(new Date());
                    //String spgstr = String.format("%s   %dKm/h   LNG:%.3f   LAT:%.3f",  Utils.putTextCPHM, Utils.putTextSpeed, Utils.latitude, Utils.longitude);
                    String spgstr = String.format("%s   %dKm/h", Utils.putTextCPHM, Utils.putTextSpeed);
                    String spgstr1 = String.format("LNG:%.3f   LAT:%.3f",Utils.latitude, Utils.longitude);

                    synchronized (mCamParameter.videosyn) {
                        if (mCamParameter.savefile) {
                            if (mCamParameter.DEV_TYPE == CamParameter.DEV_TYPE_MIPI
                                    ) {
                                /*mCamParameter.setWatermarkex(0, suffix, 10, 10, 20);
                                mCamParameter.setWatermarkex(1, spgstr, 10, height2_v - 100, 20);
                               mCamParameter.setWatermarkex(2, spgstr1, 10, height2_v - 50, 20);*/

                                if (mMainCameraDevice != null) {
                                    CameraDevice.Parameters parameters = mMainCameraDevice.getParameters();
                                    if(parameters != null){
                                        spgstr = "粤"+spgstr;
                                        String strEx1 = new String(spgstr.getBytes(),"UTF-8");
                                        String strEx2 = new String(spgstr1.getBytes(),"UTF-8");
                                        parameters.setWatermarkTextAreaEx1(20, 750, 1000, 830);
                                        parameters.setWatermarkTextEx1(strEx1);
                                        parameters.setWatermarkTextAreaEx2(20, 850, 1000, 930);
                                        parameters.setWatermarkTextEx2(strEx2);
                                        mMainCameraDevice.setParameters(parameters);
                                    }
                                }
  
                            } else if (mCamParameter.DEV_TYPE == CamParameter.DEV_TYPE_USB) {
                                /*if (IsWatermarkexDate)
                                    mCamParameter.setWatermarkex(0, suffix, 10, 10, 20);*/

                                mCamParameter.setWatermarkex(1, spgstr, 10, height1_v - 120, 1);
                                mCamParameter.setWatermarkex(2, spgstr1, 10, height1_v - 70, 1);
                            }
                        }
                    }
                    sleep(1000);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }

    int number = 0;

    private class FaceDeleteThread extends Thread {
        private CamParameter mCamParameter = null;

        public void run() {
            if (Build.VERSION.SDK_INT >= 9) {
                while (mCamParameter == null) {
                    for (int i = 0; i < CamService.CamNumber; i++) {
                        if ((CamService.camParameters[i] != null && CamService.camParameters[i].IMG_TYPE == CamParameter.FMT_TYPE_H264 && CamService.camParameters[i].DEV_TYPE == CamParameter.DEV_TYPE_USB)) {
                            mCamParameter = CamService.camParameters[i];
                            break;
                        }
                    }
                }
            }

            Mat faceMat = null;

            while (true) {
                if (FaceStatus == 1) {
                    boolean hasFrame = false;

                    if (mCamParameter.cameraFrameReady[1]) {
                        if (!mCamParameter.mFrameChain[1].empty()) {
                            faceMat = mCamParameter.mCameraFrame[1].rgba();
                        }
                        hasFrame = true;
                    }

                    if (hasFrame && faceMat != null) {
//                            Imgcodecs.imwrite("/sdcard/faces/image/image" + number++ + ".jpg", faceMat);
//                            if (number > 10)
//                                number = 0;
                        EasyFace.getInstance().nativeProcessFrame(faceMat.getNativeObjAddr(), faceMat.rows(), faceMat.cols());
                        mCamParameter.cameraFrameReady[1] = false;
                        faceMat = null;
                    }
                } else {
                    try {
                        sleep(500);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }

//    @SuppressLint({
//            "SimpleDateFormat", "NewApi"
//    })
//    public interface OnCamDrawListener {
//        void notifyBmpupdate(Bitmap bmp1, Bitmap bmp2);
//    }
//
//    /**
//     * 更新进度的回调接口
//     */
//    private OnCamDrawListener onCamDrawListener;
//
//    @SuppressLint("NewApi")
//    class DrawLoop extends Thread {
//        public void run() {
//            while (true) {
//                synchronized (camParameters[0].videosyn) {
//                    synchronized (camParameters[1].videosyn) {
//                        if (camParameters[0].getBmp() != null && camParameters[0].getBmp() != null)
//                            onCamDrawListener.notifyBmpupdate(camParameters[0].getBmp(), camParameters[1].getBmp());
//                    }
//                }
//
//                try {
//                    sleep(100);
//                } catch (Exception e) {
//                    e.printStackTrace();
//                }
//            }
//        }
//    }
//
//    /**
//     * 注册回调接口的方法，供外部调用
//     * @param onProgressListener
//     */
//    public void setOnCamDrawListener(OnCamDrawListener onProgressListener) {
//        this.onCamDrawListener = onProgressListener;
//    }
//
//    /**
//     * 返回一个Binder对象
//     */
//    @Override
//    public IBinder onBind(Intent intent) {
//        return new CamBinder();
//    }
//
//    public class CamBinder extends Binder {
//        /**
//         * 获取当前Service的实例
//         * @return
//         */
//        public CamService getService(){
//            return CamService.this;
//        }
//    }
//
//    public Handler handler = new Handler(){
//        @Override
//        public void handleMessage(Message msg) {
//            super.handleMessage(msg);
//            if (msg.what == 1){
//                startVideo_playbackLoop(msg.arg1);
//            }
//        }
//    };
//
//    public  void startVideo_playbackLoop(int camId){
//        loop = new x264Video_playbackLoop(camId);
//        loop.start();
//    }
//
//
//    /**
//     * 视频回放线程
//     */
//    public static String filePath[] = {null,null};
//    class x264Video_playbackLoop extends Thread {
//        private CamParameter mCamParameter = null;
//        private Socket socket = null;
//        private BufferedReader input = null;
//        private PrintStream output = null;
//        private int camID = 0;
//        private boolean start_stop = true;
//
//        byte Frametype = 0;
//
//        int i = 0, j = 0, n = 0, pos = 0;long len = 0;
//        long sendtime;
//        Date senddate;
//        ByteBuffer timebuffer = ByteBuffer.allocate(8);
//
//        x264Video_playbackLoop(int id) {
//            camID = id;
//        }
//
//        public void run() {
//
//            FileInputStream inputStream = null;
//            byte[] outData = null;
//            byte []start = new byte[4];
//            long len264 = 0;
//            boolean isFirst = true;
//
//            try {
//
//                socketClose();
//
//                /**
//                 * 文件格式：0 0 0 1.....0 0 0 1...
//                 * 每一帧都是以0 0 0 1 开始
//                 */
//                while (true) {
//
//                    try {
//                        //如果实时视频正在进行，则当前通道的回放则不能进行
//                        if (isSendServer[camID] && isSend1209[camID]){
//                            if (x264Loop != null){
//                                x264Loop.socketClose();
//                            }
//                        }
//
//                        if (!isSendServer_record[camID] && !isSend120a[camID]){
//                            socketClose();
//                            continue;
//                        }
//
//                        if (len264 == 0){
//                            if (filePath[camID] == null){
//                                e(TAG,"filePath==null" );
//                                sleep(1000);
//                                continue;
//                            }
//
////                            File file = new File("/storage/emulated/0/MediaData/CarMainMedia_B66666/Video/2017-06-20/20170620113330-107520.264");
//                            File file = new File(filePath[camID]);
//                            e(TAG,"filePath==="+file.exists());
//                            if(file == null || !file.exists()){
//                                sleep(1000);
//                                continue;
//                            }
//
//                            inputStream = new FileInputStream(file);
//                        }
//                        byte data[] = new byte[100000];
//                        int a = 0;
//                        int startLen = 0;
//
////                        inputStream.read(data);
////                        Log.e(TAG,"--start==="+Hex.encodeHexStr(data,data.length));
////                        sleep(10000);
//
//                        //判断一帧的开始和结束，并复制到outData
//                        while (true){
//                            if ((startLen = inputStream.read(start)) > 0){
//
//                                //Log.e(TAG,"start==="+Hex.encodeHexStr(start,startLen));
//
//                                //<4 || == 0，说明读取结束
//                                if (startLen < 4){
//                                    outData = new byte[a+startLen+1];
//                                    if (startLen != 0){
//                                        System.arraycopy(start,0,data,a,startLen);
//                                    }
//                                    System.arraycopy(data,0,outData,0,a+startLen+1);
//                                    break;
//                                }
//
//                                //一帧开始 以0 0 0 1 开始
//                                if( a == 0 ){
//                                    //如果不是第一帧，后面加0 0 0 1
//                                    if (!isFirst ){
//                                        System.arraycopy(new byte[]{0,0,0,1},0,data,a,4);
//                                        a += 4;
//                                    }
//                                    e(TAG,"一帧开始==");
//                                }
//
//                                int beginStart = Hex.ByteArraytoInt(start);
//
//                                //如果不是0 0 0 1开始，则继续读，直到读取到第一帧数据
//                                if (isFirst && a == 0 && beginStart != 1){
//                                    continue;
//                                }
//
//                                //一帧结束
//                                if (a != 0 && beginStart == 1){
//                                    outData = new byte[a-4+1];
//                                    System.arraycopy(data,0,outData,0,a-4+1);
//                                    len264 = outData.length;
//                                    e(TAG,"一帧结束=="+len264+",outData="+Hex.encodeHexStr(outData,50));
//                                    break;
//                                }
//
//                                //保存数据到data
//                                System.arraycopy(start,0,data,a,startLen);
//
//                                a += startLen;
//                                isFirst = false;
//                            }
//                        }
//
//                        //数据类型
//                        switch(outData[4] & 0x1F)
//                        {
//                            case 0x00: case 0x05:
//                            Frametype = 1;//FRAME_P;
//                            break;
//                            case 0x01: case 0x06:
//                            Frametype = 2;//FRAME_B;
//                            break;
//                            case 0x02: case 0x07:
//                            Frametype = 0;//FRAME_I;
//                            break;
//                            case 0x03: case 0x08:
//                            Frametype = 1;//FRAME_P;
//                            break;
//                            case 0x04: case 0x09:
//                            Frametype = 0;//FRAME_I;
//                            break;
//                        }
//
//                        //推送RTP到服务器
//                        if(isSendServer_record[camID] && !ServerIP_record[camID].isEmpty()){
//                            //Log.e("ServerIP", " = " + ServerIP[camID]);
//                            try {
//                                if(socket == null){
//                                    InetAddress serverAddr = InetAddress.getByName(ServerIP_record[camID]);
//
//                                    socket = new Socket(serverAddr, ServerTCP_record[camID]);
//                                    output = new PrintStream(socket.getOutputStream(), true);//, "utf-8"
//
//                                    input = new BufferedReader(new InputStreamReader(socket.getInputStream()));
//
//                                }
//                                //注册视频通道
//                                if(isSend120a[camID]){
//                                    len = Cmd120a[camID].length;
//                                    //实时音视频媒体通道注册
//                                    if(len >= 13){
//                                        byte[] Send120a = new byte[4096];
//                                        j = 0;
//                                        Send120a[j++] = 0x7E;
//                                        for (i = 0; i < len; i++) {
//                                            if (Cmd120a[camID][i] == 0x7E) {
//                                                Send120a[j++] = 0x7D;
//                                                Send120a[j++] = 0x02;
//                                            } else if (Cmd120a[camID][i] == 0x7D) {
//                                                Send120a[j++] = 0x7D;
//                                                Send120a[j++] = 0x01;
//                                            } else {
//                                                Send120a[j++] = Cmd120a[camID][i];
//                                            }
//                                        }
//                                        Send120a[j++] = 0x7E;
//
//                                        output.write(Send120a, 0, j);
//                                        output.flush( );
//                                        Thread.sleep(100);
//                                        //                                    char[] str = new char[1024];
//                                        //                                    len = input.read(str);
//                                        //
//                                        InputStream stream = socket.getInputStream();
//                                        byte[] redbuff = new byte[100];
//                                        int count = stream.read(redbuff);
//
//                                        e(TAG,"count=="+count);
//                                        if(count >= 13 && redbuff[0] == 0x7E && redbuff[1] == 0x80 && redbuff[2] == 0x01 ){
//                                            e("Cmd120a", "收到0x8001通用应答！！！");
//                                        }
//
//                                        isSend120a[camID] = false;
//                                    }
//                                }
//                                synchronized (camParameters[camID].videosyn) {
//
//                                    //组RTP数据包，并发送数据包。
//                                    if(len264 > 0){
//                                        //                                    Log.e("H264DATA", "Data Len = " + len264);
//                                        // 推送视频流
//                                        pos = 0;
//
//                                        sendtime = System.currentTimeMillis();
//                                        senddate = new Date(sendtime);
//
//                                        timebuffer.putLong(0, sendtime);
//
//                                        for(i = 0; len264 > 0; i++) {             //分包发送
//                                            len = len264 > 1400 ? 1400 : len264;
//
//                                            byte[] sendbuff = new byte[(int) (26 + len)];
//
//                                            sendbuff[0] = 0x30;
//                                            sendbuff[1] = 0x31;
//                                            sendbuff[2] = 0x63;
//                                            sendbuff[3] = 0x64;
//
//                                            //包序号
//                                            sendbuff[4] = (byte) ((i >> 8) & 0xFF);
//                                            sendbuff[5] = (byte) (i & 0xFF);
//
//                                            //帧ID
//                                            sendbuff[6] = (byte) ((n >> 8) & 0xFF);
//                                            sendbuff[7] = (byte) (n & 0xFF);
//
//                                            //数据类型
//                                            sendbuff[8] = Frametype;             //
//
//                                            //负载类型
//                                            sendbuff[9] = (byte)(0x80 | 0x62);             //98,H264
//
//                                            //时间戳
//                                            System.arraycopy(timebuffer.array(), 0, sendbuff, 10, 8);
//
//                                            //绝对时间
//                                            sendbuff[18] = (byte)((((senddate.getYear() / 10) % 10)<< 4) + (senddate.getYear() % 10));
//                                            sendbuff[19] = (byte)(((((senddate.getMonth() + 1) / 10) % 10)<< 4) + ((senddate.getMonth() + 1) % 10));
//                                            sendbuff[20] = (byte)((((senddate.getDate() / 10) % 10)<< 4) + (senddate.getDate() % 10));
//                                            sendbuff[21] = (byte)((((senddate.getHours() / 10) % 10)<< 4) + (senddate.getHours() % 10));
//                                            sendbuff[22] = (byte)((((senddate.getMinutes() / 10) % 10)<< 4) + (senddate.getMinutes() % 10));
//                                            sendbuff[23] = (byte)((((senddate.getSeconds() / 10) % 10)<< 4) + (senddate.getSeconds() % 10));
//
//                                            //数据体长度
//                                            sendbuff[24] = (byte) ((len >> 8) & 0xFF);
//                                            sendbuff[25] = (byte) (len & 0xFF);
//
//                                            System.arraycopy(outData, pos, sendbuff, 26, (int) len);
//
//                                            output.write(sendbuff, 0, sendbuff.length);
//                                            output.flush( );
//
//                                            sendbuff = null;
//
//                                            pos += 1400;
//                                            len264 -= 1400;
//                                        }
//                                        e("SendVideo9509", "发送完一帧数据9505，包数：" + i +"  Data Len = " + (len264 + pos));
//                                        n++;                //发送一帧，帧数自增。
//                                    }
//                                }
//
//                            } catch (UnknownHostException e1) {
//                                e1.printStackTrace();
//                            } catch (IOException e1) {
//                                e1.printStackTrace();
//                            }
//
//                        }
//
//                        sleep(200);
//                    } catch (Exception e) {
//                        e.printStackTrace();
//                    }
//                }
//
//            } catch (Exception e) {
//                e.printStackTrace();
//            }
//        }
//
//        //
//        public void socketClose(){
//            if (socket != null){
//                try {
//                    socket.close();
//                } catch (IOException e) {
//                    e.printStackTrace();
//                }
//                socket = null;
//            }
//
//        }
//    }
//

    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    public static int SetVideoPara(int flag, int lock, int width1, int height1, int width2, int height2, int vediosave1, int vediosave2) {

        boolean camrest1 = false, camrest2 = false, reboot = false;

        if (flag != -1 && (flag == 0 || flag == 1)) {
            flag_v = flag;              //标记   0：不标记   1：标记
            camrest1 = true;
            camrest2 = true;
        }

        if (lock != -1 && (lock == 0 || lock == 1)) {
            lock_v = lock;              //锁存   0：不锁存   1：锁存
            camrest1 = true;
            camrest2 = true;
        }

        if (vediosave1 != -1 && (vediosave1 == 0 || vediosave1 == 1)) {
            vediosave1_v = vediosave1;  //通道1存储     0：不存储   1：存储
            camrest1 = true;
        }
        if (vediosave2 != -1 && (vediosave2 == 0 || vediosave2 == 1)) {
            vediosave2_v = vediosave2;  //通道2存储     0：不存储   1：存储
            camrest2 = true;
        }

        if ((width1 != width1_v || height1 != height1_v) && ((width1 == 1280 && height1 == 720) || (width1 == 640 && height1 == 480))) {
            width1_v = width1;          //通道1录像宽
            height1_v = height1;        //通道1录像高

            MyApplication.editor.putInt("width1_v", width1_v);
            MyApplication.editor.putInt("height1_v", height1_v);
            MyApplication.editor.commit();
            camrest1 = true;
            reboot = true;
            vediosave1_v = 0;
            vediosave2_v = 0;
        }

        if ((width2 != width2_v || height2 != height2_v) && ((width2 == 1280 && height2 == 720) || (width2 == 640 && height2 == 480))) {
            width2_v = width2;          //通道2录像宽
            height2_v = height2;        //通道2录像高

            MyApplication.editor.putInt("width2_v", width2_v);
            MyApplication.editor.putInt("height2_v", height2_v);
            MyApplication.editor.commit();
            camrest2 = true;
            reboot = true;
            vediosave1_v = 0;
            vediosave2_v = 0;
        }

        if (camrest1) {
            for (int i = 0; i < CamNumber; i++) {
                if (camParameters[i].savefile || i != camMIPI_ID) {
                    camParameters[i].saveStart = 0;
                }
            }
        } else if (camrest2) {
            if (camParameters[camMIPI_ID].savefile) {
                camParameters[camMIPI_ID].saveStart = 0;
            }
        }
        if (reboot) {
            try {
                Thread.sleep(3000);
                //Utils.execCommand("reboot");
                android.os.Process.killProcess(android.os.Process.myPid());
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return 0;
    }
}
